﻿using System;

namespace PacMan3D.Utils
{
    /// <summary>
    /// This class represents a 3D Point, composed by floats.
    /// </summary>
    public class Point3D
    {
        public float X { get; set; }
        public float Y { get; set; }
        public float Z { get; set; }
        public float H { get; set; }

        public Point3D()
            : this(0.0f, 0.0f, 0.0f) { }


        public Point3D(float x, float y)
            : this(x, y, 0.0f) { }

        public Point3D(float x, float y, float z) 
        {            
            this.X = x;
            this.Y = y;
            this.Z = z;
            this.H = 1.0f;
        }

        public Point3D Clone()
        {
            return new Point3D(this.X, this.Y, this.Z);
        }

        public bool IsEqualXZ(Point3D p)
        {
            return ((this.X == p.X) && (this.Z == p.Z));
        }

        /// <summary>
        /// Método que calcula a equacao do plano com base em tres pontos.
        /// </summary>
        /// <param name="v0"></param>
        /// <param name="v1"></param>
        /// <param name="v2"></param>
        /// <returns></returns>
        public static float[] CalculaPlano(float[] v0, float[] v1, float[] v2)
        {
            float[] plano = new float[4];
            float[] vec0 = new float[3];
            float[] vec1 = new float[3];

            // Calculo de dois Vectores para achar a instersecção
            vec0[0] = v1[0] - v0[0];
            vec0[1] = v1[1] - v0[1];
            vec0[2] = v1[2] - v0[2];

            vec1[0] = v2[0] - v0[0];
            vec1[1] = v2[1] - v0[1];
            vec1[2] = v2[2] - v0[2];

            // Encontra o produto de interseção para adquirir A, B, e C da equacao do plano 
            plano[0] = vec0[1] * vec1[2] - vec0[2] * vec1[1];
            plano[1] = -(vec0[0] * vec1[2] - vec0[2] * vec1[0]);
            plano[2] = vec0[0] * vec1[1] - vec0[1] * vec1[0]; 
            plano[3] = -(plano[0] * v0[0] + plano[1] * v0[1] + plano[2] * v0[2]);

            return plano;
        }


        public override string ToString()
        {
            return "Point{X: " + this.X + ", Y: " + this.Y + ", Z: " + this.Z + "}";
        }
    }
}
